package bb.lanxing.mvp.presetner;

import android.bluetooth.BluetoothProfile;
import android.content.DialogInterface;
import android.util.Log;

import com.besall.allbase.bluetooth.service.Protocol.ProtocolService;
import com.besall.allbase.common.utils.FileUtils;
import com.besall.allbase.view.activity.chipstoollevel4.protocol.ProtocolPresenter;

import org.json.JSONException;
import org.json.JSONObject;
import org.litepal.LitePal;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import bb.lanxing.App;
import bb.lanxing.R;
import bb.lanxing.lib.devices.sgsettingentity.routebook.Route;
import bb.lanxing.lib.devices.sgsettingentity.routebook.Routebooks;
import bb.lanxing.model.database.RouteBook;
import bb.lanxing.model.database.PostQueue;
import bb.lanxing.model.database.RouteBookInfo;
import bb.lanxing.model.json.RouteBookComment;
import bb.lanxing.mvp.model.PostQueueModelImpl;
import bb.lanxing.mvp.model.RouteInfoModelImpl;
import bb.lanxing.mvp.model.i.IRouteInfoModel;
import bb.lanxing.mvp.presetner.i.IPostQueueModel;
import bb.lanxing.mvp.presetner.i.IRouteBookInfoPresenter;
import bb.lanxing.mvp.view.i.IRouteInfoView;
import bb.lanxing.util.RouteBookUtil;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;

public class RouteBookInfoPresenterImpl extends BasePresenter implements IRouteBookInfoPresenter {
    private static final String TAG = "RouteInfoPresenterImpl";
    private final IRouteInfoView infoView;
    private final IPostQueueModel postQueueModel = new PostQueueModelImpl();
    private final IRouteInfoModel infoModel = new RouteInfoModelImpl();

    public RouteBookInfoPresenterImpl(IRouteInfoView infoView) {
        this.infoView = infoView;
    }

    @Override
    public void requestRouteInfo(RouteBook routeBook, final boolean downLoad, final int launchMode) {
        if (downLoad) {
            this.infoView.showLoadingDialog(R.string.dialog_downloading, true);
        }
        addSubscription(this.infoModel.requestRouteInfo(routeBook).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        if (downLoad) {
                            infoView.dismissLoadingDialog();
                        }
                        infoView.refreshComplete();
                    }

                    @Override
                    public void onNext(RouteBook routeBook2) {
                        infoView.refreshComplete();
                        infoView.onRequestRouteInfoResult(routeBook2, downLoad, launchMode);
                    }
                }));
    }

    @Override
    public void queryRouteBook(RouteBook routeBook, final int launchMode) {
        addSubscription(this.infoModel.queryLushu(routeBook).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        infoView.dismissLoadingDialog();
                        infoView.refreshComplete();
                    }

                    @Override
                    public void onNext(RouteBook routeBook2) {
                        infoView.refreshComplete();
                        infoView.onRequestRouteInfoResult(routeBook2, false, launchMode);
                    }
                }));
    }

    @Override
    public void requestRouteComment(final RouteBook routeBook, final boolean needClean) {
        requestRouteComment(routeBook, 0);
    }

    @Override
    public void requestRouteComment(final RouteBook routeBook, final int offset) {
        addSubscription(this.infoModel.requestCommentFromServers(routeBook, offset)
                .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        infoView.refreshComplete();
                    }

                    @Override
                    public void onNext(List<RouteBookComment> routeBookComments) {
                        infoView.onRequestRouteCommentResult(routeBookComments, routeBook, offset == 0);
                        infoView.refreshComplete();
                    }
                }));
    }

    @Override
    public void getPostQueue(long routeServersId) {
        this.postQueueModel.getTypedPostQueue(PostQueue.TYPE_LUSHU_COMMENT, routeServersId, true)
                .delay(500L, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(postQueues -> {
                    if (infoView != null) {
                        infoView.onSendCommentNegativeResult(postQueues);
                    }
                });
    }

    @Override
    public void deleteRouteComment(long routeServersId, long commentServersId) {
        addSubscription(this.infoModel.deleteRouteComment(routeServersId, commentServersId)
                .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        infoView.dismissLoadingDialog();
                        App.getContext().showMessage(e.getMessage());
                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        infoView.onRouteCommentDeleteResult(aBoolean);
                    }
                }));
    }

    @Override
    public void handleCollectRoute(final RouteBook routeBook, final int type) {
        addSubscription(this.infoModel.routeCollectionControl(routeBook.getServerId(), type)
                .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        infoView.handleCollectionResult(false, type, routeBook);
                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        infoView.handleCollectionResult(aBoolean, type, routeBook);
                    }
                }));
    }

    @Override
    public void downloadRoute(RouteBook routeBook, final int launchMode, final boolean needCredits) {
        addSubscription(this.infoModel.downloadRoute(routeBook).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        infoView.dismissLoadingDialog();
                    }

                    @Override
                    public void onNext(RouteBook routeBook2) {
                        infoView.dismissLoadingDialog();
                        infoView.onDownLoadRouteResult(routeBook2, needCredits, launchMode);
                    }
                }));
    }

    @Override
    public void downloadRoute(long serverId) {
        this.infoView.showLoadingDialog(R.string.syncing_workout, true,
                (DialogInterface.OnCancelListener) this.infoView);
        addSubscription(this.infoModel.downloadRoute(serverId).subscribe(new Subscriber<>() {
            @Override
            public void onCompleted() {
                Log.d(TAG, " downloadRoute onCompleted ");
                // infoView.getActivity().runOnUiThread(infoView::dismissLoadingDialog);//remove by wangsm
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, " downloadRoute error, serverId: " + serverId);
                infoView.getActivity().runOnUiThread(infoView::dismissLoadingDialog);
                infoView.getActivity().runOnUiThread(() -> {
                    infoView.toast("Download Error");
                });
            }

            @Override
            public void onNext(String s) {
                RouteBookInfo routeBookInfo;

                try {
                    JSONObject jsonObject = new JSONObject(s);
                    String msg = jsonObject.getString("msg");
                    String ext = jsonObject.getString("ext");
                    String content = jsonObject.getString("content");
                    String json_url = jsonObject.getString("name");
                    int size = jsonObject.getInt("fileSize");
                    double distance = jsonObject.getDouble("distance");
                    String type = jsonObject.getString("sportType");
                    String version = jsonObject.getString("version");
                    int source = jsonObject.getInt("sourceType");
                    int gain = (int) jsonObject.getDouble("elevationGain");
                    String title = jsonObject.getString("title");
                    String filePath = RouteBookUtil.saveDirectionFile(content, serverId, ext);

                    Log.d(TAG, " the routebook serverId is: " + serverId);
                    Log.d(TAG, " the routebook filePath is: " + filePath);
                    List<RouteBookInfo> list =
                            LitePal.where("serverId = ?", String.valueOf(serverId)).find(RouteBookInfo.class);
                    Log.d(TAG, " list.size is: " + list.size());

                    if (!list.isEmpty()) {
                        routeBookInfo = list.get(0);
                        Log.d(TAG, " the routebookinfo db exist,id: " + routeBookInfo.getId());
                    } else {
                        Log.d(TAG, " new the routebookinfo");
                        routeBookInfo = new RouteBookInfo();
                    }
                    routeBookInfo.setJson_url(json_url);
                    routeBookInfo.setTitle(title);
                    routeBookInfo.setDistance(distance);
                    routeBookInfo.setSourceType(source);
                    routeBookInfo.setSportType(type);
                    routeBookInfo.setElevationGain(gain);
                    routeBookInfo.setServerId(String.valueOf(serverId));
                    routeBookInfo.setFilePath(filePath);
                    routeBookInfo.setExt(ext);
                    routeBookInfo.save();
                    // end by wangsm

                    // if the device is connected,will update the routebooks.json,send routebooks.json,send the
                    // routebook file to device.
                    Route newRoute = new Route(null, null, json_url, title, String.valueOf(serverId), distance, type, -1,
                            version, false, source, gain);
                    newRoute.setExt(ext);
                    Log.d(TAG, " route information ,begin write the routebooks.json,s: " + s);
                    // add by wangsm for update routebooks.json
                    Log.d(TAG, " route information,serverId: " + serverId);
                    ProtocolPresenter protocolPresenter = ProtocolPresenter.getInstance();
                    if (protocolPresenter != null) {
                        ProtocolService protocolService = protocolPresenter.getProtocolService();
                        if (protocolService == null) {
                            Log.d(TAG, " pls connect the device ");
                            infoView.getActivity().runOnUiThread(() -> {
                                infoView.toast(R.string.pls_conn_device);
                                infoView.getActivity().runOnUiThread(infoView::dismissLoadingDialog);// dismiss dialog
                            });
                            return;
                        }
                        int state = protocolService.getDeviceConnectState();
                        if (protocolService != null && protocolService.isConnect
                                && state == BluetoothProfile.STATE_CONNECTED) {
                            Routebooks routebooks = FileUtils.parseRouteBooksJson(infoView.getActivity());
                            Log.d(TAG, " the device is connected,update the routebook.json to send ");
                            List<Route> routes = null;
                            if (routebooks == null) {
                                routes = new ArrayList<>();
                                routes.add(newRoute);
                                // FileUtils.createRouteBooks(infoView.getActivity(), routes);
                            } else {
                                routes = routebooks.routes;
                                int index = 0;
                                for (index = 0; index < routes.size(); index++) {
                                    Route route = routes.get(index);
                                    Log.d(TAG, " the route rid:" + route.getRid());
                                    if (route.getRid().equals(String.valueOf(serverId))) {
                                        Log.d(TAG, " set new route");
                                        routes.set(index, newRoute);
                                        break;
                                    }
                                }
                                // Route newRoute = new Route(null,null, json_url, title, String.valueOf(serverId),
                                // size, type, -1, version, false,source,gain);
                                Log.d(TAG, " the route list index: " + index);
                                Log.d(TAG, " the route list size: " + routes.size());
                                if (index == routes.size()) {
                                    Log.d(TAG, " add new route");
                                    routes.add(newRoute);
                                }
                                /*
                                 * boolean result = FileUtils.createRouteBooks(infoView.getActivity(), routes);
                                 * if(result){ Log.d(TAG," begin send the routebooks.json"); //filePath List<String>
                                 * filePathList = new ArrayList<>(); filePathList.add(filePath);
                                 * FileUtils.sendRouteBooksJsonFile(infoView.getActivity(),protocolPresenter,
                                 * filePathList); }
                                 */
                            }
                            boolean result = FileUtils.createRouteBooks(infoView.getActivity(), routes);
                            if (result) {
                                Log.d(TAG, " begin send the routebooks.json");
                                // filePath
                                List<String> filePathList = new ArrayList<>();
                                filePathList.add(filePath);
                                FileUtils.sendRouteBooksJsonFile(infoView.getActivity(), protocolPresenter,
                                        filePathList);
                            }
                        } // protocolService != null && protocolService.isConnect
                    } // protocolPresenter != null
                    // end by wangsm*/

                } catch (JSONException e) {
                    e.printStackTrace();
                    infoView.getActivity().runOnUiThread(() -> {
                        infoView.toast(R.string.toast_download_failed);
                    });
                }
            }
        }));
    }

    @Override
    public void readCommentsFromCache(final RouteBook routeBook) {
        addSubscription(this.infoModel.readCommentsFromCache(routeBook).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(List<RouteBookComment> routeBookComments) {
                        infoView.onRequestRouteCommentResult(routeBookComments, routeBook, true);
                    }
                }));
    }
}
